use crate::entity::sys_menu::SysMenu;
use crate::entity::{fetch_page, Page, PaginationOptions};
use crate::service::DATE_FORMAT;
use crate::vo::sys_menu_vo::{SysMenuAddReq, SysMenuPageReq};
use crate::SQLX;
use anyhow::anyhow;
use chrono::Local;
use salvo::{Depot, Request};

pub struct MenuService {}

impl MenuService {
    pub async fn add_menu(request: &mut Request) -> anyhow::Result<()> {
        let menu = request.parse_json::<SysMenuAddReq>().await?;
        let menu = SysMenu {
            menu_id: None,
            parent_id: menu.parent_id,
            menu_name: menu.menu_name,
            permission: menu.permission,
            path: menu.path,
            create_time: Some(Local::now().format(DATE_FORMAT).to_string()),
            url: menu.url,
            r#type: menu.r#type,
        };
        let result = menu.add_menu().await;
        Ok(())
    }

    pub async fn del_menu(request: &mut Request) -> anyhow::Result<()> {
        let menu_id = request
            .query::<i64>("menu_id")
            .ok_or(anyhow::anyhow!("menu not found "))?;
        let sqlx = SQLX.get().ok_or(anyhow!("db error"))?;
        let mut db = sqlx.acquire().await?;
        sqlx::query(r#"delete from sys_menu where menu_id =?"#).bind(menu_id).execute(&mut *db).await?;
        Ok(())
    }

    pub async fn menu_page(
        request: &mut Request,
        depot: &mut Depot,
    ) -> anyhow::Result<Page<SysMenu>> {
        let menu_page_req = request.parse_json::<SysMenuPageReq>().await?;

        let paginate_option = PaginationOptions { page_no: menu_page_req.page_no, page_size: menu_page_req.page_size };
        let mut sql = r#"select * from sys_menu where 1=1 "#.to_string();
        if menu_page_req.menu_name.is_some() {
            sql.push_str(&format!("and menu_name like '%{}%'", menu_page_req.menu_name.unwrap()));
        }
        let page = fetch_page::<SysMenu>(&sql, &paginate_option).await?;
        Ok(page)
    }
}
